package com.wwj.my_ummary.util.redisutls;

import com.wwj.my_ummary.util.SerUtils;
import com.wwj.my_ummary.util.SpringContextHolder;
import org.springframework.data.redis.core.RedisCallback;
import org.springframework.data.redis.core.RedisTemplate;

import java.util.Objects;
import java.util.Set;

/**
 * redis工具类
 */
public class RedisHelper {

    private static final RedisTemplate<String, String> redisTemplate = SpringContextHolder.getBean("redisTemplate");

    public static Boolean select(final Integer dbKey) {
        return redisTemplate.execute((RedisCallback<Boolean>) connection -> {
            connection.select(dbKey);
            return true;
        });
    }

    public static Boolean setNX(final String key, final Object obj) {
        return redisTemplate.execute((RedisCallback<Boolean>) connection -> (boolean) connection.setNX(key.getBytes(), Objects.requireNonNull(SerUtils.serializeObj(obj))));
    }

    /**
     * 存入对象到redis中
     *
     * @param key
     * @param obj
     * @return
     */
    public static Boolean set(final String key, final Object obj) {
        return redisTemplate.execute((RedisCallback<Boolean>) connection -> {
            connection.set(key.getBytes(), Objects.requireNonNull(SerUtils.serializeObj(obj)));
            return true;
        });
    }

    /**
     * 设置对象并设置过期时间
     *
     * @param key
     * @param obj
     * @param minute
     * @return
     */
    public static Boolean setEX(final String key, final Object obj, Integer minute) {
        //分钟转化成秒
        final long time = minute * 60;
        return redisTemplate.execute((RedisCallback<Boolean>) connection -> {
            connection.setEx(key.getBytes(), time, Objects.requireNonNull(SerUtils.serializeObj(obj)));
            return true;
        });
    }

    /**
     * 获取redis中的对象
     *
     * @param key
     * @return
     */
    public static String get(final String key) {
        return redisTemplate.execute((RedisCallback<String>) connection -> {
            byte[] result1 = connection.get(key.getBytes());
            if (null == result1 || null == SerUtils.unserializeObj(result1)) {
                return "";
            }
            return Objects.requireNonNull(SerUtils.unserializeObj(result1)).toString();
        });
    }

    /**
     * 获取redis中的对象
     *
     * @param key
     * @return
     */
    public static Object getObj(final String key) {
        return redisTemplate.execute((RedisCallback<Object>) connection -> {
            byte[] result1 = connection.get(key.getBytes());
            if (null == result1 || null == SerUtils.unserializeObj(result1)) {
                return "";
            }
            return SerUtils.unserializeObj(result1);
        });
    }

    public static Boolean sadd(final String key, final String obj) {
        return redisTemplate.execute((RedisCallback<Boolean>) connection -> {
            Long addResult = connection.sAdd(key.getBytes(), obj.getBytes());
            return addResult > 0;
        });
    }

    public static Boolean srem(final String key, final String val) {
        return redisTemplate.execute((RedisCallback<Boolean>) connection -> {
            Long sremResult = connection.sRem(key.getBytes(), val.getBytes());
            return sremResult > 0;
        });
    }

    public static Boolean expire(final String key, final Integer time) {
        return redisTemplate.execute((RedisCallback<Boolean>) connection -> (boolean) connection.expire(key.getBytes(), time));
    }

    /**
     * 删除redis中的对象
     *
     * @param key
     * @return
     */
    public static Boolean del(final String key) {
        redisTemplate.execute((RedisCallback<Boolean>) connection -> {
            connection.del(key.getBytes());
            return true;
        });
        return true;
    }

    /**
     * 批量删除
     *
     * @param key
     * @return
     */
    public static Boolean batchDel(final String key) {
        final String keys = key + "*";
        return redisTemplate.execute((RedisCallback<Boolean>) connection -> {
            Set<byte[]> set = connection.keys(keys.getBytes());
            assert set != null;
            for (byte[] bytes : set
            ) {
                connection.del(bytes);
            }
            return true;
        });
    }

}
